<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>异步回调与记录队列</title>
</head>
<body>
</body>
<script>
  /** 1.异步回调与记录队列
   *    a.MutationObserver 接口是出于性能考虑而设计的，其核心是异步回调与记录队列模型。
   *    b.为了在大量变化事件发生时不影响性能，每次变化的信息（由观察者实例决定）会保存在 MutationRecord 实例中，然后添加到记录队列。
   *    c.这个队列对每个 MutationObserver 实例都是唯一的，是所有 DOM 变化事件的有序列表。
   * **/


  /** 2.记录队列
   *    a.每次 MutationRecord 被添加到 MutationObserver 的记录队列时，仅当之前没有已排期的微任务回调时（队列中微任务长度为 0），
   *      才会将观察者注册的回调（在初始化 MutationObserver 时传入）作为微任务调度到任务队列上。这样可以保证记录队列的内容不会被回调
   *      处理两次。
   *    b.不过在回调的微任务异步执行期间，有可能又会发生更多变化事件。因此被调用的回调会接收到一个 MutationRecord 实例的数组，顺序为
   *      它们进入记录队列的顺序。回调要负责处理这个数组的每一个实例，因为函数退出之后这些实现就不存在了。回调执行后，这些 
   *      MutationRecord 就用不着了，因此记录队列会被清空，其内容会被丢弃。
   *    c.takeRecords()方法：调用 MutationObserver 实例的 takeRecords() 方法可以清空记录队列，取出并返回其中的所有 
   *      MutationRecord 实例。看这个例子：
   * **/

   function checkTakeRecords(){
     let mutationObserver = new MutationObserver( mutationRecords=>{console.log(mutationRecords);});
     mutationObserver.observe(document.body,{ attributes:true });
     document.body.className = 'bar';
     document.body.className = 'foo';
     document.body.className = 'quz';
     console.log(mutationObserver.takeRecords());
     console.log(mutationObserver.takeRecords());
   }
  //  checkTakeRecords();
  //  Array(3)
  //  Array(0)
</script>
</html>
